package com.giscloud.commons.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPAddressUtils {

    protected final static Logger log = LoggerFactory.getLogger(IPAddressUtils.class);

    public static String getIpAddress(HttpServletRequest request) {

        String remoteIp = request.getHeader("X-Forwarded-For");
        log.debug("X-Forwarded-For:"+remoteIp);
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getHeader("X-Real-IP");
            log.debug("X-Real-IP:"+remoteIp);
        }
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getHeader("Proxy-Client-IP");
            log.debug("Proxy-Client-IP:"+remoteIp);
        }
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getHeader("WL-Proxy-Client-IP");
            log.debug("WL-Proxy-Client-IP:"+remoteIp);
        }
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getHeader("HTTP_CLIENT_IP");
            log.debug("HTTP_CLIENT_IP:"+remoteIp);
        }
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getHeader("HTTP_X_FORWARDED_FOR");
            log.debug("HTTP_X_FORWARDED_FOR:"+remoteIp);
        }
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getRemoteAddr();
            log.debug("request.getRemoteAddr:"+remoteIp);
        }
        if (remoteIp == null || remoteIp.isEmpty()
                || "unknown".equalsIgnoreCase(remoteIp)) {
            remoteIp = request.getRemoteHost();
            log.debug("request.getRemoteHost:"+remoteIp);
        }
        log.debug("getFirstAddress(remoteIp):"+getFirstAddress(remoteIp));
        return getFirstAddress(remoteIp);
    }

    private static boolean isUnknown(String str) {
        return StringUtils.isBlank(str) || "unknown".equalsIgnoreCase(StringUtils.trimToEmpty(str));
    }

    private static String getFirstAddress(String str) {
        Matcher matcher = IP_ADDRESS_PATTERN.matcher(str);
        return (matcher.find() ? matcher.group() : null);
    }

    private static final Pattern IP_ADDRESS_PATTERN = Pattern
            .compile("[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}");
}
